﻿    using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using AutoPartsSearch.Domain.Abstract.Repositories;
using System.Data.SqlClient;
using AutoPartsSearch.Domain.Common;
using AutoPartsSearch.Domain.Entities.Enums;
using Dapper;
using AutoPartsSearch.Domain.Entities;
using AutoPartsSearch.Domain.Abstract;

namespace AutoPartsSearch.Domain.Concrete.Repositories
{
    public class DapperSellerRepository : BaseRepository, ISellerRepository
    {
        public DapperSellerRepository(ILanguageGetter languageGetter)
            : base(languageGetter)
        {
        }

        public IEnumerable<Entities.Seller> GetBySearchQuery(Entities.SearchQuery searchQuery)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@QueryId", searchQuery.Id, DbType.Int32);
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            var sellers = QueryExecutor.QueryDynamic<Seller>("sp_GetSellersBySearchQuery", ModelReader, param);
            return sellers;
        }

        public Seller GetByCode(Guid code)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Code", code, DbType.Guid);
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            return QueryExecutor.QueryDynamic<Seller>("sp_GetSellerByCode", ModelReader, param).FirstOrDefault();
        }

        public int Add(Entities.Seller instance)
        {
            int id = 0;
            var param = new Dapper.DynamicParameters();
            param.Add("@Id", id, DbType.Int32, ParameterDirection.Output);
            param.Add("@INN", instance.INN, DbType.String);
            param.Add("@FullName", instance.FullName, DbType.String);
            param.Add("@CompanyName", instance.CompanyName, DbType.String);
            param.Add("@Adress", instance.Adress, DbType.String);
            param.Add("@City", instance.City.Id, DbType.Int32);
            param.Add("@EMail", instance.EMail, DbType.String);
            param.Add("@Phone", instance.Phone, DbType.String);
            param.Add("@Phone2", instance.Phone2, DbType.String);
            param.Add("@MobilePhone", instance.MobilePhone, DbType.String);
            param.Add("@Site", instance.Site, DbType.String);
            param.Add("@CarBrands", Converter.ToXml(instance.CarBrands));
            param.Add("@PartGroups", Converter.ToXml(instance.PartGroups));
            param.Add("@IsDeliveryOnlyToRegion", instance.IsDeliveryOnlyToRegion, DbType.Boolean);
            param.Add("@ReceiveQueriesByEmail", instance.ReceiveQueriesByEmail, DbType.Boolean);
            param.Add("@IsBlocked", false, DbType.Boolean);
            param.Add("@Expired", instance.Expired.Date, DbType.Date);
            param.Add("@DirectorName", instance.DirectorName, DbType.String);
            param.Add("@IsIndividual", instance.IsIndividual, DbType.Boolean);
            param.Add("@Created", DateTime.Now.Date, DbType.Date);
            QueryExecutor.ExecuteProcedure("sp_AddSeller", param);
            return param.Get<int>("@Id");
        }

        public void Update(Entities.Seller instance)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@INN", instance.INN, DbType.String);
            param.Add("@FullName", instance.FullName, DbType.String);
            param.Add("@CompanyName", instance.CompanyName, DbType.String);
            param.Add("@Adress", instance.Adress, DbType.String);
            param.Add("@City", instance.City.Id, DbType.Int32);
            param.Add("@EMail", instance.EMail, DbType.String);
            param.Add("@Phone", instance.Phone, DbType.String);
            param.Add("@Phone2", instance.Phone2, DbType.String);
            param.Add("@MobilePhone", instance.MobilePhone, DbType.String);
            param.Add("@Site", instance.Site, DbType.String);
            param.Add("@CarBrands", Converter.ToXml(instance.CarBrands));
            param.Add("@PartGroups", Converter.ToXml(instance.PartGroups));
            param.Add("@IsDeliveryOnlyToRegion", instance.IsDeliveryOnlyToRegion, DbType.Boolean);
            param.Add("@ReceiveQueriesByEmail", instance.ReceiveQueriesByEmail, DbType.Boolean);
            param.Add("@IsBlocked", instance.IsBlocked, DbType.Boolean);
            param.Add("@Sign", instance.Sign, DbType.String);
            param.Add("@DirectorName", instance.DirectorName, DbType.String);
            QueryExecutor.ExecuteProcedure("sp_UpdateSeller", param);
        }

        

        public void UpdateExpiredDate(int id, DateTime date)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Id", id, DbType.Int32);
            param.Add("@Expired", date.Date, DbType.Date);
            QueryExecutor.ExecuteProcedure("sp_UpdateSellerExpiredDate", param);
        }

        public Entities.Seller GetById(int id)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Id", id, DbType.Int32);
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            return QueryExecutor.QueryDynamic<Seller>("sp_GetSellerById", ModelReader, param).FirstOrDefault();
        }

        public Entities.Seller GetByCompanyName(string companyName)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@CompanyName", companyName, DbType.String);
            param.Add("@CurrentTimeUtc", DateTime.Now, DbType.DateTime);
            param.Add("@UpdateLastActivity", true, DbType.Boolean);
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            return QueryExecutor.QueryDynamic<Seller>("sp_GetSellerByCompanyName", ModelReader, param).FirstOrDefault();
        }

        public void Block(int id, bool block)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Id", id, DbType.Int32);
            param.Add("@IsBlocked", block, DbType.Boolean);
            QueryExecutor.ExecuteProcedure("sp_BlockSeller", param);
        }

        public void Quote(int id, bool enable)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Id", id, DbType.Int32);
            param.Add("@IsEnabled", enable, DbType.Boolean);
            QueryExecutor.ExecuteProcedure("sp_SellerEnableQuote", param);
        }

        public IEnumerable<Entities.Seller> Get(int page, int pageSize)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            param.Add("@Page", page, DbType.Int32);
            param.Add("@PageSize", pageSize, DbType.Int32);
            return QueryExecutor.QueryDynamic<Seller>("sp_GetSellersPaged", ModelReader, param);
        }

        public IEnumerable<Entities.ExtendedSeller> GetExtendedSellers(int page, int pageSize)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            param.Add("@Page", page, DbType.Int32);
            param.Add("@PageSize", pageSize, DbType.Int32);
            return QueryExecutor.QueryDynamic<ExtendedSeller>("sp_GetSellersPaged", ExtendedModelReader, param);
        }


        public void Delete(int id)
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Id", id, DbType.Int32);
            QueryExecutor.ExecuteProcedure("sp_DeleteSeller", param);
        }

        public long GetTotalCount()
        {
            return QueryExecutor.QueryProcedure<int>("sp_GetSellerTotalCount").FirstOrDefault();
        }


        public IEnumerable<Seller> Get()
        {
            var param = new Dapper.DynamicParameters();
            param.Add("@Lang", this.CurrentLanguage, DbType.String);
            var sellers = QueryExecutor.QueryDynamic<Seller>("sp_GetSellers", ModelReader, param);
            return sellers;
        }

        private void ModelReader(Seller seller, dynamic o)
        {
            seller.Id = o.Id;
            seller.Adress = o.Adress;
            seller.CarBrands = Converter.FromXml(o.CarBrands);
            seller.City = new Dictionary(o.City);
            seller.CompanyName = o.CompanyName;
            seller.EMail = o.EMail;
            seller.FullName = o.FullName;
            seller.INN = o.INN;
            seller.IsBlocked = o.IsBlocked;
            seller.IsDeliveryOnlyToRegion = o.IsDeliveryOnlyToRegion;
            seller.MobilePhone = o.MobilePhone;
            seller.PartGroups = Converter.FromXml(o.PartGroups);
            seller.Phone = o.Phone;
            seller.Phone2 = o.Phone2;
            seller.ReceiveQueriesByEmail = o.ReceiveQueriesByEmail;
            seller.Site = o.Site;
            seller.Code = o.Code;
            seller.Expired = o.Expired;
            seller.Sign = o.Sign;
            seller.DirectorName = o.DirectorName;
            seller.Created = o.Created;
            seller.IsIndividual = o.IsIndividual;
            seller.IsQuoteEnabled = o.IsQuoteEnabled;
        }

        private void ExtendedModelReader(ExtendedSeller seller, dynamic o)
        {
            ModelReader(seller, o);
            seller.LastActivityDate = o.LastActivityDate;
            seller.DayOffersCount = o.DayOffersCount;
            seller.TotalOffersCount = o.TotalOffersCount;
            seller.LastOfferDate = o.LastOfferDate;
        }
    }
}
